package dd.prog2.musterExercises.ws12set08_word_cnt;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TreeMap;

/**
 * Finds the frequency of occurrence of each word in a text file.
 * 
 * @author Ruediger Lunde
 */
public class WordFrequencyCounter {
	private int lineCount;
	private int wordCount;
	/** Maintains the number of occurrences for each word in the text. */
	private final TreeMap<String, Integer> frequencyMap = new TreeMap<String, Integer>();

	/**
	 * Analyzes the words in the specified file and updates the word frequency
	 * counter attributes accordingly.
	 * 
	 * @param file
	 *            An ASCII file.
	 */
	public void analyzeText(File textFile) {
		lineCount = 0;
		wordCount = 0;
		frequencyMap.clear();
		try {
			BufferedReader in = new BufferedReader(new FileReader(textFile));
			// Iterate through each line of the file
			while (true) {
				String currLine = in.readLine();
				if (currLine == null)
					break;
				analyzeLine(currLine);
			}
		} catch (IOException ex) {
			System.out.println("Error occurred while reading from "
					+ textFile.getAbsolutePath() + ":");
			System.out.println(ex);
		}
	}

	private void analyzeLine(String line) {
		System.out.println(line);
		// Use only lower case letters for text analysis
		line = line.toLowerCase();

		// Iterate through each word of the current line
		// Delimit words based on whitespace, punctuation, and quotes
		StringTokenizer parser = new StringTokenizer(line, " \t\n\r\f.,;:!?\"");
		if (parser.hasMoreElements())
			lineCount++;
		while (parser.hasMoreTokens()) {
			String currWord = parser.nextToken();
			wordCount++;

			Integer frequency = frequencyMap.get(currWord);
			if (frequency == null)
				frequency = 0;
			frequencyMap.put(currWord, frequency + 1);
		}
	}

	/** Describes the result of the last text file analysis. */
	public void printResults() {
		List<Entry<String, Integer>> wordFrequencies = new ArrayList<Entry<String, Integer>>();
		for (Entry<String, Integer> entry : frequencyMap.entrySet())
			wordFrequencies.add(entry);
		System.out.println("\nLine Count: " + lineCount);
		System.out.println("Word Count: " + wordCount);
		System.out.println("Frequency of occurrence of each word:");
		Collections.sort(wordFrequencies, new EntryComparator());
		int i = 0;
		for (Entry<String, Integer> entry : wordFrequencies) {
			System.out.printf("%10s : %3d ", entry.getKey(), entry.getValue());
			if (++i % 5 == 0)
				System.out.println();
		}
	}

	/**
	 * Tests the word frequency counter using a song text file. The file
	 * Song.txt should be placed in a sub-directory named data in the project
	 * root directory (e.g. PROG-TI2/data/Song.txt).
	 */
	public static void main(String[] args) {
		WordFrequencyCounter counter = new WordFrequencyCounter();
		counter.analyzeText(new File("data/Song.txt"));
		counter.printResults();
	}
}
